﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Text.RegularExpressions;
using UnityEngine.Networking.Match;
using UnityEngine.Networking.NetworkSystem;

public class Lobby : MonoBehaviour {
    private static Lobby _instance;
    public static Lobby Instance { get => _instance; }

    [SerializeField] GameObject roomGameContainerPfb;

    [SerializeField] Canvas lobbyCanvas;
    [SerializeField] Canvas roomCanvas;
    [SerializeField] Canvas scuffleCanvas;
    [SerializeField] ScrollRect hostScroll;
    [SerializeField] GameObject hostListItemPfb;
    [SerializeField] TMPro.TMP_Dropdown dropDown;

    [SerializeField] TMPro.TMP_InputField nicknameTmp;
    [SerializeField] LanManager discovery;
    [SerializeField] MyNetworkManager network;
    [SerializeField] float lobbyItemLifetime;

    [SerializeField] Button btnReadyAndStart;
    [SerializeField] TMPro.TextMeshProUGUI txtReadyAndStart;

    public string NickName { get; set; }
    public Transform RoomGameContainerTrans { get => roomGameContainerTrans; }

    Dictionary<string, HostListItem> hostListItemDic;
    bool isHost;
    int gameState = 0; // 0: notReady, 1: ready, 2: start
    Transform roomGameContainerTrans;

    private void Awake() {
        _instance = this;
        hostListItemDic = new Dictionary<string, HostListItem>();
    }
    public void Start() {
        discovery.Initialize();
        discovery.StartAsClient();
        discovery.OnReceiveClbk = OnDetectedRoom; 
    }

    #region UI_Clbk
    public void BackToStartMenu() {
        SceneManager.LoadScene("Scenes/StartMenu");
    }
    public void BackToLobby() {
        if (isHost) {
            network.StopHost();
        } else {
            network.StopClient();
        }

        lobbyCanvas.enabled = true;
        roomCanvas.enabled = false;
        scuffleCanvas.enabled = false;

        if (!discovery.isClient) { 
            discovery.StopBroadcast();
            discovery.Initialize();
            discovery.StartAsClient();
            network.StopHost();
        }

        DestroyRoomGameContainer();
    }
    /// <summary>
    /// 被输入框控件调用
    /// </summary>
    public void UpdateNickName() {
        NickName = nicknameTmp.text;
    }
    public void CreateRoom() {
        isHost = true;

        discovery.broadcastData = $"{nicknameTmp.text},{network.matchPort},{dropDown.value},{network.numPlayers + 1}/{network.maxConnections}";
        discovery.StopBroadcast();
        discovery.Initialize();
        discovery.StartAsServer();

        network.StartHost();

        gameState = GameStateMsgType.READY;
    }
    public void OnReadyAndStart() {
        if (isHost) {
            // 进入游戏
            // - 切换场景
            // - 创建玩家面板
            // - 由客户端来摆放面板位置
            // - 开始游戏 
            // - 结束游戏
            // - 回到房间
            network.ServerChangeScene("MultiGame");
        } else { 
            // 如果未准备，就发送准备消息；如果已准备，就发送取消准备消息
            // Debug.Log(myClient.connection.isReady);
            if (GameStateMsgType.NOT_READY == gameState) {
                gameState = GameStateMsgType.READY;
                myClient.Send(MyMsgType.Ready, new IntegerMessage(GameStateMsgType.READY));
                txtReadyAndStart.text = "Not Ready";
            } else if (GameStateMsgType.READY == gameState) {
                gameState = GameStateMsgType.NOT_READY;
                myClient.Send(MyMsgType.Ready, new IntegerMessage(GameStateMsgType.NOT_READY));
                txtReadyAndStart.text = "Ready";
            }
        }
    }
    #endregion

    private void Update() {
        var removedKeyList = new List<string>();
        foreach (var pair in hostListItemDic) {
            if (pair.Value.Lifetime > lobbyItemLifetime) {
                Destroy(pair.Value.gameObject);
                removedKeyList.Add(pair.Key);
            }
        }
        foreach (var key in removedKeyList) {
            hostListItemDic.Remove(key);
        }
    }

    private void OnDetectedRoom(string fromAddress_, string roomName_, 
                                int port_, int gameMode_, string slotCount_) {
        // Debug.Log($"{fromAddress_}, {roomName_}, {port_}, {(GameType)gameMode_}, {slotCount_}");
        if (!hostListItemDic.TryGetValue(fromAddress_, out var lobbyItem)) {
            // 创建一个 LobbyItem
            var go = Instantiate(hostListItemPfb, hostScroll.content);
            var rTrans = go.GetComponent<RectTransform>();
            rTrans.sizeDelta = new Vector2(hostScroll.content.rect.width, rTrans.sizeDelta.y);
            lobbyItem = go.GetComponent<HostListItem>();
            hostListItemDic.Add(fromAddress_, lobbyItem);
        }
        lobbyItem.Refresh(roomName_, (GameType)gameMode_, slotCount_, fromAddress_, port_);
        lobbyItem.JoinBtnClbk = JoinIntoARoom;
    }

    NetworkClient myClient;
    private void JoinIntoARoom(string address_, int port_) {
        isHost = false;
        network.networkAddress = address_;
        myClient = network.StartClient();
        gameState = GameStateMsgType.NOT_READY;
    }

    public void OpenRoomWindow() {
        lobbyCanvas.enabled = false;
        roomCanvas.enabled = true;
        scuffleCanvas.enabled = true;

        if (isHost) { 
            txtReadyAndStart.text = "Start";
            //btnReadyAndStart.interactable = false;
        } else {
            txtReadyAndStart.text = "Ready";
            //btnReadyAndStart.interactable = true;
        }

        CreateRoomGameContainer();
    }
    public void RefreshLobbyStartBtn() {
        if (network.LobbyPlayerCount > 1) {
            btnReadyAndStart.interactable = network.CheckIsAllClientGetReadyInLobby();
        } else {
            btnReadyAndStart.interactable = true;
        }
    }

    private void CreateRoomGameContainer() {
        roomGameContainerTrans = Instantiate<GameObject>(roomGameContainerPfb).transform;
    }
    private void DestroyRoomGameContainer() {
        Destroy(roomGameContainerTrans.gameObject);
    }
}
